package com.most.security;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

public class TokenFilter extends BasicHttpAuthenticationFilter {
  private static final Logger log = LoggerFactory.getLogger(TokenFilter.class);

  @Override
  protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    try {
      return executeLogin(request, response);
    } catch (Exception e) {
      log.error("TokenFilter|isAccessAllowed|error", e);
    }
    return false;
  }

  @Override
  protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
    HttpServletRequest httpServletRequest = (HttpServletRequest)request;
    String authToken = httpServletRequest.getHeader("Authorization");
    return StringUtils.isNotBlank(authToken);
  }

  @Override
  protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
    try {
      HttpServletRequest httpServletRequest = (HttpServletRequest)request;
      String encryptedToken = httpServletRequest.getHeader("Authorization");
      if (StringUtils.isEmpty(encryptedToken)){
        onLoginFail(response);
        return false;
      }
      StatelessAuthToken authToken = new StatelessAuthToken();
      authToken.setEncryptedToken(encryptedToken);
      getSubject(request, response).login(authToken);
      return true;
    }catch (Exception e){
      onLoginFail(response);
    }
    return false;

  }
  //登录失败时默认返回 401 状态码
  private void onLoginFail(ServletResponse response) throws IOException {
    try {
      HttpServletResponse httpServletResponse = (HttpServletResponse)response;
      httpServletResponse.setStatus(401);
      httpServletResponse.setContentType("application/json");
      httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
      PrintWriter writer = response.getWriter();
      writer.print(JSON.toJSONString("未授权"));
      writer.flush();
      writer.close();
    } catch (IOException e) {
      log.error("TokenFilter|response401|error", e);
    }
  }

  @Override
  protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
    sendChallenge(request, response);
    return false;
  }

}
